package benchmarks;

import java.io.IOException;

import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;

import edu.vub.at.exceptions.InterpreterException;
import edu.vub.at.objects.ATAbstractGrammar;
import edu.vub.at.objects.ATObject;
import edu.vub.at.objects.natives.NATText;
import edu.vub.at.objects.natives.grammar.AGAssignField;



public class Benchmark extends SimpleBenchmark {
	//TODO 
	//Alle ASM 3.x dependencies voor een librarie (weet niet meer dewelke) interferen met kryo welke absoluut ASM 4.0 nodig heeft!
	//GSON -> register an InstanceCreator for the more difficult serializations nl AGCopy and ParseTreeSerialization
	//Kryo ParseTreeCopy doet moeilijk zie mail dries
	
	
	//@Param({"GSonLib", "KryoLib", "ProtostuffLib", "XStreamLib" })
	//@Param({"SmartJSONLib", "JacksonLib", "FlexJSONLib", "CastorLib", "NativeJava","GSonLib", "KryoLib", "ProtostuffLib", "XStreamLib"})
	@Param({"FlexJSONLib", "JSONIOLib", "NativeJava","GSonLib", "KryoLib", "ProtostuffLib", "XStreamLib", "XStreamDomDriverLib", "XStreamStaxDriverLib"})
	private String library;
	
	private TestMethods currentLib;
	
	public static String resultsPath = "Results/";
	
	public static String[] benchmarkMethods = {"TXTSerialization", "TXTDeserialization", "TXTCopy"};//{"TXTCopy", "AGCopy", "ParseTreeCopy", "IsolateCopy"};
		
	@Override
	protected void setUp() throws InterpreterException, IOException,
			IllegalAccessException, ClassNotFoundException,
			InstantiationException {

		new TestClasses();

		Class<?> klass = Class.forName("benchmarks." + library);;
		currentLib = (TestMethods) klass.newInstance();
		
		//TestClasses.serializedBoeTXT = currentLib.serialize(TestClasses.boeTXT);
		//TestClasses.serializedAss = currentLib.serialize(TestClasses.ass);
		//TestClasses.serializedAG = currentLib.serialize(TestClasses.ag);
		//TestClasses.serializedIsolate = currentLib.serialize(TestClasses.isolate);
		//TestClasses.serializedIsolateRefPair = currentLib.serialize(TestClasses.isolatePair);
	}

	public void timeTXTSerialization(int reps) throws IOException {
		for (int i = 0; i < reps; ++i) {
			currentLib.serialize(TestClasses.boeTXT);
		}
	}

	public void timeTXTDeserialization(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.deserialize(TestClasses.serializedBoeTXT, NATText.class);
		}
	}

	public void timeTXTCopy(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.copy(TestClasses.boeTXT);
		}
	}

	public void timeAGSerialization(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.serialize(TestClasses.ass);
		}
	}
	
	public void timeAGDeserialization(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.deserialize(TestClasses.serializedAss, AGAssignField.class);
		}
	}

	public void timeAGCopy(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.copy(TestClasses.ass);
		}
	}

	public void timeParseTreeSerialization(int reps) throws IOException {
		for (int i = 0; i < reps; ++i) {
			currentLib.serialize(TestClasses.ag);
		}
	}

	public void timeParseTreeDeserialization(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.deserialize(TestClasses.serializedAG, ATAbstractGrammar.class);
		}
	}

	public void timeParseTreeCopy(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.copy(TestClasses.ag);
		}
	}
	
	public void timeIsoletSerialization(int reps) throws IOException {
		for (int i = 0; i < reps; ++i){
			currentLib.serialize(TestClasses.isolate);
		}
	}
	
	public void timeIsolateDeserialization(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.deserialize(TestClasses.serializedIsolate, ATObject.class);
		}
	}
	
	public void timeIsolateCopy(int reps) throws IOException,
			ClassNotFoundException {
		for (int i = 0; i < reps; ++i) {
			currentLib.copy(TestClasses.isolate);
		}
	}
	
	
	// TODO VEEL MEER TIMEMETHODE!
	// "--measureMemory"
	public static void main(String[] args) throws Exception {
		String methods = "";

		methods += benchmarkMethods[0];
		for(int i = 1; i < benchmarkMethods.length; i++){
			methods += "," + (benchmarkMethods[i]);
		}

		Runner.main(Benchmark.class, new String[] {"-Dbenchmark=" + methods, "--timeUnit", "ns", "--saveResults", resultsPath, "--trials", "1"});
		
	}
}
